package main

import (
	//"fmt"
	"net/http"
	"strconv"
	"text/template"

	"github.com/bitly/go-simplejson"
)

const (
	MaxBufferSize = 64 * 1024
)

var (
	chartArgs    = make(map[string]string)
	tcpDataArr   = make([]uint32, MaxBufferSize)
	kcpDataArr   = make([]uint32, MaxBufferSize)
	tcpDataCount uint32
	kcpDataCount uint32
)

func Init() {
	chartArgs["ChartType"] = "spline"
	chartArgs["Title"] = "KCP、TCP网络延迟对比"
	chartArgs["SubTitle"] = "最近一分钟的网络延迟数据"
	chartArgs["YAxisText"] = "Latency (ms)"
	chartArgs["XAxisNumbers"] = "1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12"
	chartArgs["ValueSuffix"] = "ms"
	chartArgs["Height"] = ""
	chartArgs["DataArray"] = "[]"
}

func updateData(lastCnt uint32) {

	if lastCnt > tcpDataCount {
		lastCnt = tcpDataCount
	}
	if lastCnt > kcpDataCount {
		lastCnt = kcpDataCount
	}
	if lastCnt > MaxBufferSize {
		lastCnt = MaxBufferSize
	}

	tcpData := make([]uint32, 0)
	kcpData := make([]uint32, 0)
	//当前数据尾部索引
	curPos := kcpDataCount % MaxBufferSize
	if curPos >= lastCnt {
		kcpData = append(kcpData, kcpDataArr[curPos-lastCnt:curPos]...)
	} else {
		headPos := MaxBufferSize - lastCnt + curPos
		kcpData = append(kcpData, kcpDataArr[headPos:]...)
		kcpData = append(kcpData, kcpDataArr[:curPos]...)
	}

	curPos = tcpDataCount % MaxBufferSize
	if curPos >= lastCnt {
		tcpData = append(tcpData, tcpDataArr[curPos-lastCnt:curPos]...)
	} else {
		headPos := MaxBufferSize - lastCnt + curPos
		tcpData = append(tcpData, tcpDataArr[headPos:]...)
		tcpData = append(tcpData, tcpDataArr[:curPos]...)
	}

	datas := make([]interface{}, 0)

	json := simplejson.New()
	json.Set("name", "TCP")
	json.Set("data", tcpData)
	datas = append(datas, json)

	json = simplejson.New()
	json.Set("name", "KCP")
	json.Set("data", kcpData)
	datas = append(datas, json)

	json = simplejson.New()
	json.Set("DataArray", datas)
	b, _ := json.Get("DataArray").Encode()
	chartArgs["DataArray"] = string(b)
}

func AddChartData(dt string, dv uint32) {
	if dt == "kcp" {
		kcpDataArr[kcpDataCount%MaxBufferSize] = dv
		kcpDataCount++
	} else if dt == "tcp" {
		tcpDataArr[tcpDataCount%MaxBufferSize] = dv
		tcpDataCount++
	} else {
		panic("the data type is invalid!")
	}
}

func handler(w http.ResponseWriter, r *http.Request) {

	values := r.URL.Query()
	cntStr := values.Get("count")
	var lastCnt int
	if len(cntStr) > 0 {
		lastCnt, _ = strconv.Atoi(cntStr)
	} else {
		lastCnt = 600
	}

	updateData(uint32(lastCnt))

	if t, err := template.New("foo").Parse(TemplateSplineHtml); err != nil {
		w.Write([]byte(err.Error()))
	} else {
		if err = t.ExecuteTemplate(w, "T", chartArgs); err != nil {
			w.Write([]byte(err.Error()))
		}
	}
}

func ListenAndServe(addr string) error {

	Init()
	http.HandleFunc("/", handler)
	http.HandleFunc("/favicon.ico", func(w http.ResponseWriter, r *http.Request) {})

	return http.ListenAndServe(addr, nil)
}
